package com.zc.hadoop.dfs;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.hadoop.fs.BlockLocation;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocalFileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.DistributedFileSystem;
import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
import org.apache.hadoop.io.IOUtils;

/**
 * HDFS 测试
 */
public class HdfsTest {

	public static void main(String[] args) throws IOException {
		// 获取集群信息
//		clusterStatus();

//		fileStatus();
		
//		rename();
		
//		move();
		
//		dirOpration();
		
		deleteDir();

//		isExists();

//		createFile();

//		readFile();
		
//		downLoad();
		
//		upLoad();
		
	}

	/**
	 * 获取集群信息
	 * 
	 * @throws IOException
	 */
	public static void clusterStatus() throws IOException {
		// 获取HDFS连接
		FileSystem fileSystem = HdfsUtil.getFs();
		// 连接到了HDFS分布式系统
		DistributedFileSystem distributedFileSystem = (DistributedFileSystem) fileSystem;
		// 得到从节点的状态
		DatanodeInfo[] data = distributedFileSystem.getDataNodeStats();

		System.out.println("==============clusterStatus=================");
		// 遍历data
		for (DatanodeInfo datanodeInfo : data) {
			// 输出从节点的信息
			System.out.println(datanodeInfo.getDatanodeReport());
		}
		System.out.println("===============clusterStatus================");
	}

	/**
	 * 集群节点
	 * 
	 * @throws IOException
	 */
	public static void fileStatus() throws IOException {
		// 获取HDFS连接
		FileSystem fileSystem = HdfsUtil.getFs();

		// 根据HDFS系统上的一个文件，指定一个集群
		Path path = new Path("/user/derek/input/1.txt");

		// 路径
		FileStatus fileStatus = fileSystem.getFileStatus(path);

		// 得到从节点的状态
		BlockLocation[] bloclLocations = fileSystem.getFileBlockLocations(fileStatus, 0,
				fileStatus.getLen());

		System.out.println("==============fileStatus=================");
		// 遍历data
		for (BlockLocation blockLocation : bloclLocations) {
			// 输出从节点的信息
			System.out.println(blockLocation.getHosts());
		}
		System.out.println("===============fileStatus================");
	}

	/**
	 * 重命名文件
	 * @throws IOException
	 */
	public static void rename() throws IOException {
		// 源文件路径
		String srcFile = "/user/derek/input/2.txt";
		// 路径不变 名字变
		String dstFile = "/user/derek/input/22.txt";
		
		FileSystem fileSystem = HdfsUtil.getFs();
		
		// 原文件的路径
		Path srcPath = new Path(srcFile);
		// 改好的文件的路径
		Path dstPath = new Path(dstFile);
		
		// 判断一下是否成功
		boolean flag = fileSystem.rename(srcPath, dstPath);
		System.out.println("==============rename=================");
		System.out.println(flag);
		System.out.println("==============rename=================");
	}

	
	/**
	 * 移动文件
	 * @throws IOException
	 */
	public static void move() throws IOException {
		String srcFile = "/user/derek/input/22.txt";
		String dstFile = "/user/2.txt";
		FileSystem fileSystem = HdfsUtil.getFs();
		Path srcPath = new Path(srcFile);
		Path dstPath = new Path(dstFile);
		boolean flag = fileSystem.rename(srcPath, dstPath);
		System.out.println("==============move=================");
		System.out.println(flag);
		System.out.println("==============move=================");
	}

	/**
	 * 创建文件夹
	 * @throws IOException 
	 * @throws IllegalArgumentException 
	 * @throws Exception
	 */
	public static void dirOpration() throws IllegalArgumentException, IOException   {
		FileSystem fileSystem = HdfsUtil.getFs();
		boolean flag = fileSystem.mkdirs(new Path("/javatest"));
		String result = flag ? "成功" : "失败";
		System.out.println("==============dirOpration=================");
		System.out.println(result);
		System.out.println("==============dirOpration=================");
	}

	/**
	 * 删除文件夹
	 * @throws IOException 
	 * @throws IllegalArgumentException 
	 * @throws Exception
	 */
	public static void deleteDir() throws IllegalArgumentException, IOException {
		FileSystem fileSystem = HdfsUtil.getFs();
		boolean flag = fileSystem.delete(new Path("/javatest"));
		String result = flag ? "su" : "fa";
		System.out.println("==============deleteDir=================");
		System.out.println(result);
		System.out.println("==============deleteDir=================");
	}

	/**
	 * 文件是否存在
	 * @throws IOException
	 */
	public static void isExists() throws IOException {
		FileSystem fileSystem = HdfsUtil.getFs();
		Path dstPath = new Path("/javatest");
		boolean flag = fileSystem.exists(dstPath);
		System.out.println("==============isExists=================");
		System.out.println(flag ? "存在" : "不存在");
		System.out.println("==============isExists=================");
	}

	
	/**
	 * 创建文件，并追加内容
	 */
	public static void createFile() {
		FileSystem fileSystem = HdfsUtil.getFs();

		// 指定HDFS的绝对路径
		Path path = new Path("/user/derek/testCreate.txt");
		
		FSDataOutputStream fsDataOutputStream = null;
		
		byte[] buff = "test content".getBytes();
		
		try {
			// 开始创建文件
			fsDataOutputStream = fileSystem.create(path);
			
			// 文件追加内容
//			fsDataOutputStream = fileSystem.append(path);
			
			// 把内容写进去
			fsDataOutputStream.write(buff, 0, buff.length);
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fsDataOutputStream != null) {
				try {
					// 关闭
					fsDataOutputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		
		
		try {
			FileStatus[] files = fileSystem.listStatus(path);
			
			for (FileStatus fileStatus : files) {
				System.out.println(fileStatus.getReplication());// 获取备份数
				System.out.println(fileStatus.getBlockSize());
				System.out.println(fileStatus.getPath());
				System.out.println(fileStatus.isDir());
				// 判断是不是符号链接
				// System.out.println(fileStatus.getSymlink());
			}
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	
	/**
	 * 读取文件内容(hdfs)
	 */
	public static void readFile() {
		FileSystem fileSystem = HdfsUtil.getFs();
		
		try {
			// 输入流打开文件系统的文件的路径
			InputStream  inputStream = fileSystem.open(new Path("/user/derek/input/1.txt"));
			
			// copy ; 4k=4096
			IOUtils.copyBytes(inputStream, System.out, 4096, true);
			
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	/**
	 * 下载到本地
	 */
	public static void downLoad() {
		FileSystem fileSystem = HdfsUtil.getFs();
		// 输入流打开文件系统的文件的路径,即源路径
		InputStream inputStream;
		try {
			inputStream = fileSystem.open(new Path("/user/derek/input/1.txt"));
			// 输出流指定到本机
			OutputStream outputStream = new FileOutputStream(new File("E:/1.txt"));
			// 复制写到本机
			IOUtils.copyBytes(inputStream, outputStream, 4096, true);
		} catch (IllegalArgumentException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 上传到HDFS
	 */
	public static void upLoad() {
		FileSystem fileSystem = HdfsUtil.getFs();
		// 连接得到本地
		LocalFileSystem localFileSystem = HdfsUtil.getLocalFS();
		// 输入流打开本地文件
		InputStream inputStream;
		try {
			inputStream = localFileSystem.open(new Path("E:/222.txt"));
			// 输出流指定到目的路径
			OutputStream outputStream = fileSystem.create(new Path("/user/derek/input/222.txt"));
			
			IOUtils.copyBytes(inputStream, outputStream, 4096, true);
		} catch (IllegalArgumentException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
}
